package net.zigin.nhi.could.waste.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.zigin.commons.util.AssertUtil;
import net.zigin.nhi.could.waste.annotation.EpiResponseFilter;
import net.zigin.nhi.could.waste.annotation.EpiResponseFilters;
import net.zigin.nhi.could.waste.annotation.LoginWhitePathAnnotation;
import net.zigin.nhi.could.waste.aop.LoginAspect;
import net.zigin.nhi.could.waste.dto.*;
import net.zigin.nhi.could.waste.exception.EpiCloudException;
import net.zigin.nhi.could.waste.exception.UnauthorizedException;
import net.zigin.nhi.could.waste.service.SysUserHospitalService;
import net.zigin.nhi.could.waste.service.SysUserService;

import net.zigin.nhi.could.waste.service.SysUserStaffService;
import net.zigin.nhi.could.waste.util.JWTUtil;
import net.zigin.nhi.could.waste.util.MD5Util;
import net.zigin.nhi.could.waste.util.RandomValidateCodeUtil;
import net.zigin.nhi.could.waste.util.SecurityUtil;
import net.zigin.nhi.could.waste.vo.JsonForResult;
import net.zigin.nhi.could.waste.vo.SysUserVo;
import net.zigin.nhi.could.waste.vo.TokenInfoBo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Locale;

/**
 * SysUser控制器类
 *
 * @author mgw1986
 * @version V1.0
 * @ClassName: SysUserController
 * @date 2021-9-7 19:08:56
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/sysUser")
public class SysUserController extends BaseController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserHospitalService sysUserHospitalService;

    @LoginWhitePathAnnotation
    @ApiOperation("账号密码登录")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    @PostMapping("/login")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "password", target = SysUserVo.class)
    })
    public JsonForResult login(@RequestBody SysUserDto userDto) {
        SysUserVo userVo = sysUserService.getUserByUserAccount(userDto.getName());
        if (userVo == null) {
            throw new EpiCloudException("用户不存在！");
        }
        if (SecurityUtil.matchesPassword(userDto.getPassword(), userVo.getPassword())) {
            SysUserVo info = sysUserService.getInfoById(userVo.getId());
            info.setToken(JWTUtil.sign(info));
            return JsonForResult.builder().data(info).success(true).build();
        } else {
            return JsonForResult.builder().message("密码错误！").success(false).build();
        }
    }

    /**
     * 查询用户详情
     *
     * @param id 用户ID
     * @return 用户详情
     */
    @LoginWhitePathAnnotation
    @GetMapping("/getById/{id}")
    @ApiOperation("查询用户详情")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "password", target = SysUserVo.class)
    })
    public JsonForResult<SysUserVo> getById(@PathVariable String id) {
        AssertUtil.isNull(id, "用户id不能为空");
        SysUserVo userVo = sysUserService.getInfoById(id);
        return JsonForResult.<SysUserVo>builder().data(userVo).success(true).build();
    }

    /**
     * 保存或编辑用户
     *
     * @param userDto 用户详情
     * @return 用户ID
     */
    @PostMapping("/save")
    @ApiOperation("保存或编辑用户")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    public JsonForResult save(@RequestBody SysUserDto userDto) {
        String id = sysUserService.saveOrUpdate(userDto);
        return JsonForResult.builder().data(id).success(true).build();
    }

    /**
     * 用户列表
     *
     * @param userDto 用户查询条件
     * @return 用户列表
     */
    @PostMapping("/getList")
    @ApiOperation("用户列表")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "password", target = SysUserVo.class)
    })
    public JsonForResult<List<SysUserVo>> getList(@RequestBody SysUserDto userDto) {
        List<SysUserVo> userList = sysUserService.getUserList(userDto);
        Integer count = sysUserService.getUserCount(userDto);
        return JsonForResult.<List<SysUserVo>>builder()
                .data(userList).total(count)
                .success(true).build();
    }

    /**
     * 获得角色关联的用户列表
     *
     * @param roleId 角色ID
     * @return 用户列表
     */
    @GetMapping("/getListByRoleId/{roleId}")
    @ApiOperation("获得角色关联的用户列表")
    @ApiImplicitParam(name = "roleId", value = "角色id", required = true, dataType = "String")
    public JsonForResult<List<SysUserVo>> getListByRoleId(@PathVariable String roleId) {
        List<SysUserVo> userVos = sysUserService.infoByRoleId(roleId);
        return JsonForResult.<List<SysUserVo>>builder().data(userVos).success(true).build();
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     * @return
     */
    @DeleteMapping("/remove/{id}")
    @ApiOperation("删除用户")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String")
    public JsonForResult remove(@PathVariable String id) {
        AssertUtil.isNull(id, "用户id不能为空");
        sysUserService.deleteByPrimaryKey(id);
        return JsonForResult.builder().success(true).build();
    }

    /**
     * 修改账户密码
     *
     * @param userDto 用户信息
     * @return
     */
    @PostMapping("/modifyPassword")
    @ApiOperation("修改账户密码")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    public JsonForResult modifyPassword(@RequestBody SysUserDto userDto) {
        sysUserService.modifyPassword(userDto);
        return JsonForResult.builder().success(true).build();
    }

    @LoginWhitePathAnnotation
    @PostMapping("/modifyPasswordWithRandomValidateCode")
    @ApiOperation("修改账户密码")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    public JsonForResult modifyPasswordWithRandomValidateCode(@RequestBody SysUserDto userDto, HttpSession session) {
        if (checkVerify(userDto.getRandomValidateCode(), session)) {
            Object code = session.getAttribute(userDto.getMobile());
            if (code != null && userDto.getSmsCode().equals(code.toString())) {
                sysUserService.modifyPasswordWithSmsCode(userDto);
                return JsonForResult.builder().success(true).build();
            }
            return JsonForResult.builder().success(false).data("短信验证码错误！").build();
        } else {
            return JsonForResult.builder().success(false).data("图形验证码错误！").build();
        }
    }

    /**
     * 发送二维码
     *
     * @param phone   电话
     * @param session
     * @return
     */
    @LoginWhitePathAnnotation
    @ApiOperation("发送短信验证码码")
    @ApiImplicitParam(name = "phone", value = "电话", required = true, dataType = "String")
    @GetMapping("sendMessage")
    public JsonForResult sendMessage(String phone, HttpSession session) {
        String smsCode = sysUserService.sendMessage(phone);//AliYunUtil.sendMessage(phone);
        if (smsCode == null) {
            return JsonForResult.builder().message("验证码发送失败！请重新发送").success(false).build();
        }
        session.setAttribute(phone, smsCode);
        session.setMaxInactiveInterval(600); // 5分钟
        return JsonForResult.builder().success(true).build();
    }

    /**
     * 验证码登录
     *
     * @param phone   电话
     * @param smsCode 验证码
     * @param session
     * @return
     */
    @LoginWhitePathAnnotation
    @ApiOperation("短信验证码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "电话", required = true, dataType = "String"),
            @ApiImplicitParam(name = "smsCode", value = "验证码", required = true, dataType = "String")
    })
    @GetMapping("loginWithSmsCode")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "activationTime,createTime,createUser,deleteTime,freezeTime,password", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "modifyTime,modifyUser,passwordTime,salt", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "isActivation,isDelete,isFreeze,isPassword", target = SysUserVo.class)
    })
    public JsonForResult loginWithSmsCode(String phone, String smsCode, HttpSession session) {
        SysUserVo userVo = sysUserService.getUserByUserPhone(phone);
        Object code = session.getAttribute(phone);
        if (code != null && smsCode.equals(code.toString())) {
            SysUserVo info = sysUserService.getInfoById(userVo.getId());
            String userStaffId = sysUserHospitalService.getIdByUserId(userVo.getId());
            info.setUserStaffId(userStaffId);
            info.setToken(JWTUtil.sign(info));
            return JsonForResult.builder().data(info).success(true).build();
        } else {
            return JsonForResult.builder().message("401").success(false).build();
        }
    }

    @LoginWhitePathAnnotation
    @ApiOperation("获取图片验证码")
    @GetMapping("/randomValidateCode")
    public void randomValidateCode(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        RandomValidateCodeUtil.getRandcode(httpServletRequest, httpServletResponse);
    }

    public boolean checkVerify(String verifyInput, HttpSession session) {
        try {
            //从session中获取随机数
            String inputStr = verifyInput;
            String random = (String) session.getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
            if (random == null) {
                return false;
            }
            if (random.toLowerCase(Locale.ROOT).equals(inputStr.toLowerCase(Locale.ROOT))) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }

    @ApiOperation("新手引导")
    @PostMapping("updateGuide")
    public JsonForResult updateGuide(@RequestBody List<String> codes) {
        sysUserService.updateGuideCode(codes);
        return JsonForResult.builder().success(true).build();
    }

    @LoginWhitePathAnnotation
    @ApiOperation("转换token")
    @PostMapping("transferToken")
    public JsonForResult transferToken(@RequestBody TokenDto token) {
        SysUserVo userVo = sysUserService.getUserByUserPhone(token.getMobile());
        SysUserVo info = sysUserService.getInfoById(userVo.getId());
        info.setToken(JWTUtil.sign(info));
        return JsonForResult.builder().data(info.getToken()).success(true).build();
    }

    @ApiOperation("获取个人信息")
    @GetMapping("getSelfInfo")
    public JsonForResult getSelfInfo(){
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        SysUserVo info = sysUserService.getInfoById(tokenInfo.getUserId());
        //info.setToken(JWTUtil.sign(info));
        return JsonForResult.builder().data(info).success(true).build();
    }

}
